package com.woniuxy.yoga.evaluate.service.impl;

import ch.qos.logback.core.boolex.EvaluationException;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.model.Result;
import com.woniuxy.yoga.commons.core.statedata.BusinessState;
import com.woniuxy.yoga.commons.core.statedata.OrderState;
import com.woniuxy.yoga.commons.core.statedata.UserState;
import com.woniuxy.yoga.evaluate.client.BusinessClient;
import com.woniuxy.yoga.evaluate.client.OrderClient;
import com.woniuxy.yoga.evaluate.client.UserClient;
import com.woniuxy.yoga.evaluate.dao.model.Evaluation;
import com.woniuxy.yoga.evaluate.dao.mapper.EvaluationMapper;
import com.woniuxy.yoga.evaluate.model.dto.businessstore.BusinessStoreByAccountIdDTO;
import com.woniuxy.yoga.evaluate.model.dto.businessstore.BusinessStoreDTO;
import com.woniuxy.yoga.evaluate.model.dto.evalution.EvaluationDTO;
import com.woniuxy.yoga.evaluate.model.dto.userinfo.UserInfoDto;
import com.woniuxy.yoga.evaluate.model.exception.EvaluateException;
import com.woniuxy.yoga.evaluate.model.exception.EvaluateExceptionCode;
import com.woniuxy.yoga.evaluate.model.form.businessstore.UpdateScoreForm;
import com.woniuxy.yoga.evaluate.model.form.evaluation.SelEvaluationForm;
import com.woniuxy.yoga.evaluate.model.dto.orderinfo.OrderInfoDto;
import com.woniuxy.yoga.evaluate.model.form.orderinfo.UpdateEvaluateStateForm;
import com.woniuxy.yoga.evaluate.model.param.evaluation.*;
import com.woniuxy.yoga.evaluate.service.EvaluationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 评价商家表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class EvaluationServiceImpl extends ServiceImpl<EvaluationMapper, Evaluation> implements EvaluationService {

    @Autowired
    private OrderClient orderClient;
    @Autowired
    private BusinessClient businessClient;
    @Autowired
    private EvaluationMapper evaluationMapper;
    @Autowired
    private UserClient userClient;

    /**
     * 用户评价服务
     * @param param
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void addServiceEvaluation(AddServiceEvaluationParam param) {
        //查询订单是否存在
        Result<OrderInfoDto> orderResult = orderClient.getByOrderNum(param.getOrderNum());
        if (orderResult.getCode()!=200) {
            throw new EvaluateException(orderResult.getCode(),orderResult.getMessage());
        }
        OrderInfoDto orderInfoDto = orderResult.getData();
        //查询订单是否已被评价
        if (orderInfoDto.getOrderEvaluationState()== OrderState.ORDER_EVALUATION_STATE_YES) {
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_EXCEPTION_CODE_ORDER_EVALUATED);
        }
        //判断是否是内部调用
        if (param.getUserId()==null) {
            param.setUserId(orderInfoDto.getUserId());
        }else if (param.getUserId()!=orderInfoDto.getUserId()){//判断是否是本人操作
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_EXCEPTION_CODE_ORDER_NOTBELONG);
        }
        //查询门店信息是否存在 是否被注销
        Result<BusinessStoreDTO> storeResult = businessClient.selByStoreId(orderInfoDto.getStoreId());
        if (storeResult.getCode()!=200) {
            throw new EvaluateException(storeResult.getCode(),storeResult.getMessage());
        }
        BusinessStoreDTO businessStoreDTO = storeResult.getData();
        //将传入参数对象赋值到评价对象上
        Evaluation evaluation = BeanUtil.toBean(param, Evaluation.class);
        evaluation.setEvaluationTime(DateUtil.format(new Date(System.currentTimeMillis()), "yyyy-MM-dd HH:mm:ss"));
        evaluation.setStoreId(businessStoreDTO.getStoreId());
        //插入到数据库
        evaluationMapper.insert(evaluation);
        //修改订单的评价状态
        if (orderInfoDto.getOrderEvaluationState()== OrderState.ORDER_EVALUATION_STATE_NO) {
            UpdateEvaluateStateForm form = BeanUtil.toBean(orderInfoDto, UpdateEvaluateStateForm.class);
            form.setEvaluateState(OrderState.ORDER_EVALUATION_STATE_YES);
            System.out.println(form);
            Result<?> result = orderClient.updateEvaluateState(form);
            if (result.getCode()!=200) {
                throw new EvaluateException(result.getCode(),result.getMessage());
            }
        }
        //计算门店评分
        LambdaQueryWrapper<Evaluation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Evaluation::getStoreId,orderInfoDto.getStoreId());
        List<Evaluation> evaluations = evaluationMapper.selectList(queryWrapper);
        //若是第一次评分则将门店评分该为该评价的评分
        if (evaluations==null||evaluations.size()==0||evaluations.size()==1) {
            businessStoreDTO.setStoreScore(Double.parseDouble(param.getRating().toString()));
        }else {
            Double total = 0.0;
            for (Evaluation evaluationOne : evaluations) {
                total+=evaluationOne.getRating();
            }
            businessStoreDTO.setStoreScore(total/evaluations.size()*1.0);
        }
        //修改数据库中门店评分
        UpdateScoreForm updateScoreForm = BeanUtil.toBean(businessStoreDTO, UpdateScoreForm.class);
        businessClient.updateScoreById(updateScoreForm);
    }

    /**
     * 商家回复评价
     * @param param
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void replyEvaluation(ReplyEvaluationParam param) {
        //判断该评价是否存在
        Evaluation evaluation = evaluationMapper.selectById(param.getEvaluationId());
        if (evaluation==null) {
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_EXCEPTION_CODE_EVALUATION_NOTEXISTS);
        }
        //查询是否已回复
        if (evaluation.getStoreReply()!=null&&(!evaluation.getStoreReply().equals(""))) {
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_EXCEPTION_CODE_EVALUATE_REPLYED);
        }
        //查询门店信息是否存在 是否被注销
        Result<BusinessStoreByAccountIdDTO> storeResult = businessClient.selBusinessStoreByAccountId(param.getAccountId());
        if (storeResult.getCode()!=200) {
            throw new EvaluateException(storeResult.getCode(),storeResult.getMessage());
        }
        BusinessStoreByAccountIdDTO dto = storeResult.getData();
        //查询该评价是否属于该门店
        if (dto.getStoreId()!=evaluation.getStoreId()) {
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_EXCEPTION_CODE_EVALUATION_NOTBELONG);
        }
        //修改数据库信息
        evaluation.setStoreReply(param.getStoreReply());
        evaluation.setReplyTime(DateUtil.format(new Date(System.currentTimeMillis()), "yyyy-MM-dd HH:mm:ss"));
        evaluationMapper.updateById(evaluation);
    }

    /**
     * 用户删除自己的评价
     * @param evaluationId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteEvaluation(Integer evaluationId,Integer userId) {
        //查询该评价是否存在
        Evaluation evaluation = evaluationMapper.selectById(evaluationId);
        if (evaluation==null) {
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_EXCEPTION_CODE_EVALUATION_NOTEXISTS);
        }
        //查询该评价是否是你自己的评价
        if (evaluation.getUserId()!=userId) {
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_EXCEPTION_CODE_EVALUATION_NOTBELONGYOU);
        }
        //删除该评价
        evaluationMapper.deleteById(evaluationId);
    }

    /**
     * 用户分页查询商家的评价
     * @param param
     * @return
     */
    @Override
    public PageInfo selEvaluation(SelEvaluationParam param) {
        //查询该商家门店是否存在是否注销
        Result<BusinessStoreDTO> storeResult = businessClient.selByStoreId(param.getStoreId());
        if (storeResult.getCode()!=200) {
            throw new EvaluateException(storeResult.getCode(),storeResult.getMessage());
        }
        BusinessStoreDTO storeResultData = storeResult.getData();
        //开始分页
        Page<Evaluation> page = new Page<>(param.getCurrent() == null ? 1 : param.getCurrent(), param.getSize() == null ? 3 : param.getSize());
        LambdaQueryWrapper<Evaluation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Evaluation::getStoreId,param.getStoreId());
        evaluationMapper.selectPage(page,wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        ArrayList<EvaluationDTO> evaluationDTOS = new ArrayList<EvaluationDTO>();
        for (Evaluation evaluation : page.getRecords()) {
            EvaluationDTO evaluationDTO = BeanUtil.toBean(evaluation, EvaluationDTO.class);
            //赋值门店名
            evaluationDTO.setStoreName(storeResultData.getStoreName());
            //查询用户信息
            Result<UserInfoDto> userResult = userClient.getByUserId(evaluation.getUserId());
            if (userResult.getCode()!=200) {
                throw new EvaluateException(userResult.getCode(),userResult.getMessage());
            }
            UserInfoDto userInfo = userResult.getData();
            //赋值用户昵称
            evaluationDTO.setUserNickName(userInfo.getUserNickName());
            //将传入前端的值保存到集合
            evaluationDTOS.add(evaluationDTO);
        }
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(evaluationDTOS);
        return pageInfo;
    }

    /**
     * 商家分页查询自己的评价
     * @param param
     * @return
     */
    @Override
    public PageInfo buselEvaluation(BuSelEvaluationParam param) {
        //查询门店信息是否存在 是否被注销
        Result<BusinessStoreByAccountIdDTO> storeResult = businessClient.selBusinessStoreByAccountId(param.getAccountId());
        if (storeResult.getCode()!=200) {
            throw new EvaluateException(storeResult.getCode(),storeResult.getMessage());
        }
        BusinessStoreByAccountIdDTO storeResultData = storeResult.getData();
        //开始分页
        Page<Evaluation> page = new Page<>(param.getCurrent() == null ? 1 : param.getCurrent(), param.getSize() == null ? 3 : param.getSize());
        LambdaQueryWrapper<Evaluation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Evaluation::getStoreId,storeResultData.getStoreId());
        evaluationMapper.selectPage(page,wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        ArrayList<EvaluationDTO> evaluationDTOS = new ArrayList<EvaluationDTO>();
        for (Evaluation evaluation : page.getRecords()) {
            EvaluationDTO evaluationDTO = BeanUtil.toBean(evaluation, EvaluationDTO.class);
            //赋值门店名
            evaluationDTO.setStoreName(storeResultData.getStoreName());
            //查询用户信息
            Result<UserInfoDto> userResult = userClient.getByUserId(evaluation.getUserId());
            if (userResult.getCode()!=200) {
                throw new EvaluateException(userResult.getCode(),userResult.getMessage());
            }
            UserInfoDto userInfo = userResult.getData();
            //赋值用户昵称
            evaluationDTO.setUserNickName(userInfo.getUserNickName());
            //将传入前端的值保存到集合
            evaluationDTOS.add(evaluationDTO);
        }
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(evaluationDTOS);
        return pageInfo;
    }

    /**
     * 用户分页查询自己的所有评价
     * @param param
     * @return
     */
    @Override
    public PageInfo selUserEvaluation(SelUserEvaluationParam param) {
        //查询用户是否存在
        Result<UserInfoDto> userResult = userClient.getByUserId(param.getUserId());
        if (userResult.getCode()!=200) {
            throw new EvaluateException(userResult.getCode(),userResult.getMessage());
        }
        UserInfoDto userInfo = userResult.getData();
        //用户账号状态是否正常
        if (userInfo.getUserState()!= UserState.USER_ACCOUNT_STATE_NORMAL) {
            throw new EvaluateException(EvaluateExceptionCode.EVALUATE_EXCEPTION_CODE_USERACCOUNTSTATE_ERROR);
        }
        //开始分页
        Page<Evaluation> page = new Page<>(param.getCurrent() == null ? 1 : param.getCurrent(), param.getSize() == null ? 3 : param.getSize());
        LambdaQueryWrapper<Evaluation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Evaluation::getUserId,param.getUserId());
        evaluationMapper.selectPage(page,wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        ArrayList<EvaluationDTO> evaluationDTOS = new ArrayList<EvaluationDTO>();
        for (Evaluation evaluation : page.getRecords()) {
            EvaluationDTO evaluationDTO = BeanUtil.toBean(evaluation, EvaluationDTO.class);
            //查询门店信息
            Result<BusinessStoreDTO> storeResult = businessClient.selByStoreId(evaluation.getStoreId());
            if (storeResult.getCode()!=200) {
                throw new EvaluateException(storeResult.getCode(),storeResult.getMessage());
            }
            BusinessStoreDTO businessStoreDTO = storeResult.getData();
            //赋值门店名
            evaluationDTO.setStoreName(businessStoreDTO.getStoreName());
            //赋值用户昵称
            evaluationDTO.setUserNickName(userInfo.getUserNickName());
            //将传入前端的值保存到集合
            evaluationDTOS.add(evaluationDTO);
        }
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(evaluationDTOS);
        return pageInfo;
    }
}
